﻿using System;
using System.Collections.Generic;
using UnityEngine;

namespace Core
{
    public class AbstractSOTable<K, T> : ScriptableObject, ISOTable
        where K : IComparable<K>
        where T : class, ITableConf<K>
    {
        //public Game G { get; set; }

#if UNITY_EDITOR
        public T[] Confs;
#else
        [SerializeField]
        protected T[] Confs;
#endif
        public int Count => Confs.Length;

        public IReadOnlyList<T> Elements => Confs;

        public IEnumerable<T> GetAll()
        {
            for (var i = 0; i < Confs.Length; i++)
            {
                yield return Confs[i];
            }
        }

        public T Get(int index)
        {
            if (index < 0 || index >= Count)
            {
                return null;
            }

            return Confs[index];
        }

        private readonly Dictionary<K, T> dict = new();
        private readonly HashSet<K> missing = new();

        public T Find(K id)
        {
            if (missing.Contains(id))
            {
                return null;
            }

            if (dict.TryGetValue(id, out var find))
            {
                return find;
            }

            for (var i = 0; i < Confs.Length; i++)
            {
                var conf = Confs[i];
                if (conf.Index.CompareTo(id) == 0)
                {
                    dict[id] = conf;
                    conf.Awake();
                    return conf;
                }
            }

            missing.Add(id);
            return null;
        }
    }
}